import { _decorator, Collider, Component, CylinderCollider, game, isValid, Node, PhysicsGroup, quat, Quat, RigidBody, SphereCollider, tween, Vec3, VERSION } from 'cc';
import { EliminateToy } from './EliminateToy';
import { eliminateConsts, EliminateMode } from './EliminateConst';
import { eliminateGameManager } from './EliminateGameManager';
import { JsonAsset } from 'cc';
import { Tween } from 'cc';
import { audioManager } from '../../common/AudioManager';
const { ccclass, property } = _decorator;

export interface TriggerEventObj {
    type: TriggerEventObj,
    selfCollider: Collider,
    otherCollider: Collider,
    impl: any,
}

export enum PhyGroup {
    DEFAULT = 1 << 0,
    TOYS = 1 << 1,
    PLANE = 1 << 2,
    CHECK = 1 << 3,
    BOARD = 1 << 4,
    IN = 1 << 5,
    SLOT = 1 << 6,
    FLY = 1 << 7
}

@ccclass('EliminateSlot')
export class EliminateSlot extends Component {

    @property(JsonAsset)
    toyRotationJson: JsonAsset = null;

    private boxCollider: Collider = null;

    /** 待消除队列，新的元素会push进该数组 */
    private _toysQueue: Node[][] = [];

    private stayY: number = 5;

    public enterSomething: boolean = false;

    public leftPos: Vec3 = new Vec3(-1.5, 10, 16);
    public rightPos: Vec3 = new Vec3(1.5, 10, 16);

    /** 落入槽子的物体 */
    public get toysQueue() {
        return this._toysQueue;
    }

    public set toysQueue(v: Node[][]) {
        this._toysQueue = v;
    }

    protected onLoad(): void {
        this.boxCollider = this.node.getComponent(Collider);
    }

    start() {
        // this.node.uuid
        console.log("slot test");
    }

    protected onEnable(): void {
        this.boxCollider.on("onTriggerEnter", this.triggerEnter, this);
        this.boxCollider.on("onTriggerStay", this.triggerStay, this);
        this.boxCollider.on("onTriggerExit", this.triggerExit, this);
    }

    protected onDisable(): void {
        this.boxCollider.off("onTriggerEnter", this.triggerEnter, this);
        this.boxCollider.off("onTriggerStay", this.triggerStay, this);
        this.boxCollider.off("onTriggerExit", this.triggerExit, this);
    }

    private _dealEnterEvent(event: TriggerEventObj) {
        if (event.otherCollider.node['clear']) {
            console.log(`${event.otherCollider.node.name} 已经被标记为clear`);
            return;
        }

        let toyComp = event.otherCollider.node.getComponent(EliminateToy);
        if (!toyComp.node['canClear']) return;

        const rb = toyComp.node.getComponent(RigidBody);
        Tween.stopAllByTarget(toyComp.node);

        // 向 toysQueue 推入
        if (this.toysQueue.length > 0) {
            const len = this.toysQueue.length - 1;
            const lastItem = this.toysQueue[len];
            if (lastItem.length > 0 && (lastItem.length < eliminateConsts.eliminateLimit)) {
                const sameType = lastItem.every(it => !it['clear'] && (it.getComponent(EliminateToy).toyId == toyComp.toyId));
                console.log("sameType is ", sameType);
                // 相同类型的放进一个数组里
                if (sameType) {
                    if (!this.toysQueue.some(toyArray => toyArray.indexOf(toyComp.node) >= 0) && !toyComp.node['clear'] && lastItem.indexOf(toyComp.node) < 0) {
                        lastItem.push(toyComp.node);
                    }
                } else {
                    const rb = toyComp.node.getComponent(RigidBody);
                    rb.useGravity = true;
                    rb.group = PhyGroup.TOYS;
                    rb.applyImpulse(new Vec3(0, 0, -15));
                    audioManager.playEffect("audio/Merge Fail");
                    console.log("进入的东西跟槽子里面的东西不同弹出去");
                }
            } else {
                if (!this.toysQueue.some(toyArray => toyArray.indexOf(toyComp.node) >= 0) && !toyComp.node['clear']) {
                    // 其他队列里面没有改对象，开辟新的待消除列表
                    this.toysQueue.push([toyComp.node]);
                }
            }
        } else {
            if (!toyComp.node['clear']) {
                // 其他队列里面没有改对象，开辟新的待消除列表
                this.toysQueue.push([toyComp.node]);
            }
        }

        console.log("toysQueue is ", this.toysQueue[this.toysQueue.length - 1].forEach(item => console.log("带消除队里：", item.name)));

        this.moveToysToRightPosAndCheck();

    }

    moveToysToRightPosAndCheck() {
        this.toysQueue.forEach(it => {
            this.moveToysToTargetPos(it).then(() => {
                // 检查是否可以消除
                const canMatch = this.checkIsCanEliminate();
                console.log("canMath is ", canMatch);
            });
        });
    }

    clearWaitNodesInBoxs(tag: string) {
        // for (let i = this.waitEnterNodes.length - 1; i >= 0; i--) {
        //     let item = this.waitEnterNodes[i];
        //     if (item['clear'] && item['tag'] == tag) {
        //         console.log("清除clear 标记的节点");
        //         this.waitEnterNodes.splice(i, 1);
        //     }
        // }
    }

    public moveToysToTargetPos(nodes: Node[]) {
        return new Promise((resolve, reject) => {
            nodes.forEach((item: Node, index: number) => {
                const rb = item.getComponent(RigidBody);
                rb.setLinearVelocity(new Vec3(0));
                rb.setAngularVelocity(new Vec3(0));
                rb.useGravity = false;
                if (rb.group != PhyGroup.IN) {
                    rb.group = PhyGroup.IN;
                }
                const name = item['tag'];
                const rotateX = this.toyRotationJson.json[name].rotateX;
                const rotateY = this.toyRotationJson.json[name].rotateY;
                const rotateZ = this.toyRotationJson.json[name].rotateZ;
                let quat = new Quat();
                Quat.fromEuler(quat, rotateX, rotateY, rotateZ);
                Tween.stopAllByTarget(item);
                if (index == 0) {
                    tween(item).to(0.2, { worldPosition: this.leftPos, rotation: quat }, { easing: 'expoOut' }).call(resolve).start();
                } else {
                    tween(item).to(0.2, { worldPosition: this.rightPos, rotation: quat }, { easing: 'expoOut' }).start();
                }
            });
        })

    }

    public triggerEnter(event: TriggerEventObj) {
        if (eliminateGameManager.gameMode == EliminateMode.MATCH3) return;
        console.log("enter", event.otherCollider.node.name);
        this._dealEnterEvent(event);
        this.enterSomething = true;
    }

    public triggerStay(event: TriggerEventObj) {
        if (eliminateGameManager.gameMode == EliminateMode.MATCH3) return;
        // console.log("stay ---- ", event.otherCollider.node.name);
    }

    public triggerExit(event: TriggerEventObj) {
        if (eliminateGameManager.gameMode == EliminateMode.MATCH3) return;
        const self = event.selfCollider;
        const other = event.otherCollider;
        if (other.node['clear']) return;

        this.enterSomething = false;
        if (other.node['myType'] == "toy") {
            const rb = other.getComponent(RigidBody);
            rb.enabled = true;
            if (rb) {
                rb.group = (PhyGroup.TOYS);
                rb.useGravity = true;
                console.log("处罚exit 弹出去", other.node.name);
                rb.applyImpulse(new Vec3(0, 0, -10));
            }

            const toyComp = other.node.getComponent(EliminateToy);
            this.removeFromBoxsOrWaitEnterNodes(toyComp.node);
        }
    }

    /**
     * 检查是否可以消除
     * @return {*}  {boolean}
     * @memberof EliminateSlotTrigger
     */
    checkIsCanEliminate(): boolean {
        // 检查待消除队列
        if (this.toysQueue.length > 0) {
            // 查看队列里面的第一个元素
            let pairNode = this.toysQueue[0];
            if (pairNode.length == eliminateConsts.eliminateLimit) {
                pairNode = this.toysQueue.shift();
                pairNode.forEach(item => {
                    const toyComp = item.getComponent(EliminateToy);
                    // 锁定触摸
                    toyComp.canTouch = false;
                });
                eliminateGameManager.uiManager.openDoor(true).then(() => {
                    eliminateGameManager.game.eliminate(pairNode).then(() => {
                        eliminateGameManager.uiManager.openDoor(false).then(() => {
                            console.log("门已经关闭");
                            eliminateGameManager.game.isEliminating = false;
                            // 递归的检查
                            this.checkIsCanEliminate();
                            eliminateGameManager.game.checkHasPair();
                        });
                    })
                });
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * 每消除一次从待消除列表里面取出一对
     * 将待消除队列里面的节点移动到boxs中并且检查是否可以消除
     */
    public moveWaitNodesToBoxs() {

        // this.checkIsCanEliminate();
    }

    removeFromBoxsOrWaitEnterNodes(node: Node) {
        for (let i = this.toysQueue.length - 1; i >= 0; i--) {
            const item = this.toysQueue[i];
            item.forEach(it => {
                if (it == node) {
                    item.splice(item.indexOf(it), 1);
                }
            })
            if (item.length == 0) {
                this.toysQueue.splice(this.toysQueue.indexOf(item), 1);
            }
        }

    }



    /**
     * 使所用的刚体静止
     */
    public staticToys() {
        // this.boxs.forEach(item => {
        //     if (!isValid(item, true)) return;
        //     const rb = item.getComponent(RigidBody);
        //     rb.useGravity = false;
        //     rb.setLinearVelocity(new Vec3(0));
        //     rb.setAngularVelocity(new Vec3(0));
        // });
    }

    public resetBoxs() {

    }

    update(deltaTime: number) {

    }
}

